 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package experiments;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author minaev
 */
public class SerExp {

    final static int COUNT_BUF = 50;

    static class MeasureSequence implements Serializable {

        int[] dat1 = new int[COUNT_BUF];
        int[] dat2 = new int[COUNT_BUF];
        int[] dat3 = new int[COUNT_BUF];
        int[] pos = new int[COUNT_BUF];
        int cnt = 0;

        public int getCnt() {
            return cnt;
        }

        public int getDat1(int n) {
            return dat1[n];
        }

        public int getDat2(int n) {
            return dat2[n];
        }

        public int getDat3(int n) {
            return dat3[n];
        }

        public int getPos(int n) {
            return pos[n];
        }

        public boolean add(int pos, int dat1, int dat2, int dat3) {
            if (cnt < COUNT_BUF) {
                this.dat1[cnt] = dat1;
                this.dat2[cnt] = dat2;
                this.dat3[cnt] = dat3;
                this.pos[cnt] = pos;
                cnt++;
                return true;
            } else {
                return false;
            }
        }
    }
    
    static class StringOutputStream extends OutputStream{
        String str;

        public StringOutputStream(String str) {
            this.str = str;
        }

        public void setStr(String str) {
            this.str = str;
        }
        
        public void addStr(String str) {
            this.str += str;
        }

        
        
        public String getStr() {
            return str;
        }
        
        char ch = 0;
        @Override
        public void write(int b) throws IOException {
            ch = (char)b;
            if(ch=='\\' || ch=='\''){
                str+='\\';
            }
            str+=(char)b;
        }
    
    }
    
    static class StringInputStream extends InputStream{
        String str;

        public StringInputStream(String str) {
            this.str = str;
        }

        public void setStr(String str) {
            this.str = str;
        }
        
        public void addStr(String str) {
            this.str += str;
        }

        
        
        public String getStr() {
            return str;
        }
        
        private int getChar(int n){
            return n<str.length()?(int)str.charAt(n):-1;
        }
        
        int cursor = 0;
        
        int ret = 0;

        @Override
        public int read() throws IOException {
            ret = getChar(cursor);
            cursor++;
            if(ret=='\\'){
                ret = getChar(cursor);
                cursor++;
            }
            return ret;
        }
    
    }

    public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {

        Random r = new Random();

        ArrayList<MeasureSequence> lst_measures = new ArrayList<MeasureSequence>();
        int cur_measure = 0;
        lst_measures.add(new MeasureSequence());

        //add
        for (int i = 0; i < COUNT_BUF * 2; i++) {
            if (!lst_measures.get(cur_measure).add(r.nextInt(3000),
                    r.nextInt(3000),
                    r.nextInt(3000),
                    r.nextInt(3000))) {
                lst_measures.add(new MeasureSequence());
                cur_measure++;
                lst_measures.get(cur_measure).add(r.nextInt(3000),
                        r.nextInt(3000),
                        r.nextInt(3000),
                        r.nextInt(3000));
            }

        }


        Connection con;
        Statement s;
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test",
                "root", "root");
        s = con.createStatement();

        String sql;
        
        StringOutputStream sos = new StringOutputStream("");
        ObjectOutputStream oos = new ObjectOutputStream(sos);
        
        long time = System.currentTimeMillis();
        for (int i = 0; i < lst_measures.size(); i++) {
            sos.setStr("INSERT INTO `ser_exp_data` "
            + "(`num_exp`, `ser_obj`) "
            + "VALUES ( 1, '");
            oos.writeObject(lst_measures.get(i));
            sos.addStr("');");
            s.execute(sos.getStr());
            
        }
        time = System.currentTimeMillis() - time;
        System.out.println("Time new method: "+time);


        time = System.currentTimeMillis();
        
        for (int i = 0; i < lst_measures.size(); i++) {
            sql = "INSERT INTO `exp_data` "
                    + "(`id_exp`, `position`, `dt1`, `dt2`, `dt3`) "
                    + "VALUES ";
            for (int j = 0; j < lst_measures.get(i).getCnt(); j++) {
                sql += "( 1," + lst_measures.get(i).getPos(j) + ", "
                        + lst_measures.get(i).getDat1(j) + ", "
                        + lst_measures.get(i).getDat2(j) + ", "
                        + lst_measures.get(i).getDat3(j) + ")";
                if (j != lst_measures.get(i).getCnt() - 1) {
                    sql += ", ";
                } else {
                    sql += ";";
                }
            }
            s.execute(sql);

        }

        time = System.currentTimeMillis() - time;

        System.out.println("Time old method:  " + time);
        
        System.out.println("Read serilization");
        
        lst_measures.clear();
        ObjectInputStream ois;
        DataInputStream dis;
        
        String ibuf="";
        int itmp=0;
        Object tmp;
        
        ResultSet rs = s.executeQuery("SELECT * FROM `ser_exp_data`;");
        while(rs.next()){
            System.out.println("row_id: "+rs.getInt(1));
            dis = new DataInputStream(rs.getBlob(3).getBinaryStream());
            ibuf = "";
            while((itmp=dis.read())!=-1){
                ibuf+=(char)itmp;
            }
            System.out.println(ibuf);
            ois=new ObjectInputStream(new StringInputStream(ibuf));
            tmp = ois.readObject();
            while(tmp!=null){
                lst_measures.add((MeasureSequence)tmp);
                tmp = ois.readObject();
            }
            //sis.setStr(rs.getBlob(2).toString());
        }
        
        for(int i=0;i<lst_measures.size();i++){
            System.out.println(i+": pos="+lst_measures.get(i).getPos(0)+
                    " dt1="+lst_measures.get(i).getDat1(0));
        }
    }
}
